package liming.ai.tool;

import liming.tool.json.ToJson;
import liming.tool.json.annotation.JsonMark;
import org.json.JSONArray;
import org.json.JSONObject;

import java.util.*;

/**
 * 工具注册中心
 * 用于对工具方法实现的注册与调用
 */
public class ToolRegistrationCenter {
    private static final Map<String,RegisterInfo> tools = new HashMap<>();
    static {
        new AutoRegistration(){
            @Override
            public String getJsonRootName() {
                return "default";
            }

            @Override
            public Class<?> getDefaultClass() {
                return AutoRegistration.class;
            }
        };
    }
    public static void registerTool(AutoRegistration registration){
        String toolName = registration.getJsonRootName().intern();
        if(!tools.containsKey(toolName)){
            tools.put(toolName,new RegisterInfo(registration));
            manageTool(toolName, ManageState.Enable);
        }
    }
    public static void registerTool(AutoRegistration... registrations){
        for (AutoRegistration registration : registrations)
            registerTool(registration);
    }

    private static RegisterInfo getRegisterInfo(String toolName){
        return tools.get(tools.containsKey(toolName)?toolName:"default");
    }

    public static AutoRegistration getTool(String toolName){
        return getRegisterInfo(toolName).toolObject;
    }

    public static boolean manageTool(String toolName, ManageState type){
        return getRegisterInfo(toolName).manageTool(type);
    }

    public static boolean manageMethod(String toolName, String methodName, ManageState type){
        return getRegisterInfo(toolName).manageMethod(methodName,type);
    }

    public static JSONObject getToolList(){
        JSONArray result = new JSONArray();
        for (RegisterInfo value : tools.values())
            if(!"default".equals(value.getJsonRootName()))
                result.put(value.serializeBody(value.getDefaultClass()).put("模块名称", value.getJsonRootName()));
        return new JSONObject().put("工具列表", result);
    }

    public static InvokeInfo invoke(String toolName,String methodName,Object... args){
        return getRegisterInfo(toolName).invoke(methodName, args);
    }

    static class RegisterInfo implements ToJson {
        private final AutoRegistration toolObject;
        @JsonMark("状态")
        private ManageState toolManageState;

        RegisterInfo(AutoRegistration toolObject){
            this.toolObject = toolObject;
            toolManageState = ManageState.Disable;
        }

        @Override
        public String getJsonRootName() {
            return toolObject.getJsonRootName();
        }

        @Override
        public JSONObject serializeBody(Class<?> type) {
            JSONArray array = new JSONArray();
            for (AutoRegistration.MethodInfo value : toolObject.methodMap.values())
                array.put(value.serializeBody(AutoRegistration.MethodInfo.class));
            return ToJson.super.serializeBody(type).put("工具方法列表",  array);
        }

        boolean manageTool(ManageState type){
            boolean result=toolObject.manageTool(type);
            if(result)
                toolManageState = type;
            return result;
        }

        boolean manageMethod(String methodName, ManageState type){
            return toolObject.manageMethod(methodName, type);
        }

        InvokeInfo invoke(String methodName,Object... args){
            if (toolManageState==ManageState.Enable)
                return toolObject.invoke(methodName, args);
            return new InvokeInfo(toolObject.getJsonRootName(), methodName, args, false, null, "工具模块未启用");
        }
    }
}
